use std::collections::HashMap;
use std::env;
use std::net::SocketAddr;

use anyhow::Result;
use config::{Config, Environment, File};
use serde::Deserialize;
use tracing::debug;

mod app;
mod provider;

use self::{app::*, provider::*};

#[derive(Debug, Deserialize)]
pub struct Settings {
    app: AppSettings,
    providers: HashMap<String, ProviderSettings>,
}

impl Settings {
    pub fn load() -> Result<Settings> {
        let run_mode = env::var("APP_RUN_MODE").unwrap_or("dev".into());
        let settings = Config::builder()
            .add_source(
                File::with_name(&format!("config/{}.yaml", run_mode.to_lowercase()))
                    .required(false),
            )
            .add_source(Environment::with_prefix("APP").separator("-"))
            .build()
            .map_err(anyhow::Error::from)?;

        settings
            .try_deserialize::<Self>()
            .map_err(Into::into)
            .map(|settings| {
                debug!("Settings: {settings:?}");
                settings
            })
    }

    pub fn app_listening_addr(&self) -> Result<SocketAddr> {
        self.app.listening_addr()
    }

    pub fn provider_settings(&self, name: &str) -> Option<&ProviderSettings> {
        self.providers.get(name)
    }
}
